<template>
  <div class="backuploadByH5">
    <h2>This is an back upload By H5's page</h2>
		<div style="position:relative">
       <div class="btnBox_back">
        <div class="hoverbtn_back"><label class="btn" for="avatar">选择图片(PNG, JPG)</label></div>
        <div class="hoverbtn_back"><label class="btn" @click="submit">上传图片</label></div>
       </div>
      	<input th:value="文件上传" style="opacity: 1" type="file" id="avatar"  name="avatar" @change="filesChange" accept="image/png, image/jpeg">
    <div slot="tip" class="upload__tip">
        只能上传jpg/png文件，且不超过500000000000kb
      </div>
      <div style="font-weight:700;" v-show="imgSrc!=''">上传图片后的图片显示</div>
    <img style="max-height:400px;max-width:400px;margin:0 auto;" v-show="imgSrc!=''" :src="imgSrc" alt="">
    </div>
    <h3 v-show="beforePreview_title==''">图片预览</h3>
    <div class="preview">
      <!--createObjectURL的预览  -->
    <div class="previewBycreateObjectURL">
    <div v-show="beforePreview_title==''">{{beforePreview_title!='' ? beforePreview_title : imgPreview1_title}}</div>
    <img v-show="beforePreview_title!=''" src="" alt="">
    <img v-show="beforePreview_title==''" :src="imgPreview1" alt="">
    </div>
    <!--createObjectURL的预览  -->
    <!-- base64的预览 -->
    <div class="previewByBase64">
    <div v-show="beforePreview_title==''">{{beforePreview_title!='' ? beforePreview_title : imgPreview2_title}}</div>
    <img v-show="beforePreview_title!=''" src="" alt="">
    <img v-show="beforePreview_title==''" :src="imgPreview2" alt="">
    </div>
    <!-- base64的预览 -->
    </div>
  </div>
</template>
<script>
import axios from "axios"; //axios用于网络请求
export default{
		name:'backuploadByH5',
		data(){
			return{
			imgPreview1:'',//图片预览 URL.createObjectURL生成对象的预览地址
      imgPreview2:'',//base64实现图片的预览
      beforePreview_title:'上传图片吧,可以生成预览',
      imgPreview1_title:'URL.createObjectURL生成图片对象地址的预览',//预览标题
      imgPreview2_title:'Base64生成的图片的预览',//预览标题
      token: "", //token 上传凭证
      uploadArea: "https://upload-z2.qiniup.com", //此处为七牛云华南区的空间地址
      domain:'http://hmytest.humianyuan.cn/',//我bucket绑定的域名，就是图片上传后的访问域名
      fileData: "",//文件对象 blob类型数据
      fileStream:'',//文件base64数据流
      fileName:'',//文件名，用于上传后的命名方式,
      imgSrc:'',//用于保存上传后的图片地址
			 }
		},
       methods: {
      // 1.用于捕获图片改变 不同于前台上传的是，使用后台完成上传，我们只需要把图片发送给后台，由后台完成上传，所以前台无需再获取token，后台自己生成token，自己发送
      filesChange(e) {
        this.imgSrc = ''//初始化
        // 1.1变量赋值
        this.fileData = e.target.files[0];//文件对象 为blob即大型二进制类型
        this.fileName = "hmytest_"+Date.now()+e.target.files[0].name;//文件重命名名
        console.log("打印文件对象:",e.target.files[0]);
        console.log("打印文件对象:",this.fileData);
        // 注意此处的图片预览我开始的时候有疑惑，为什么不直接获取用户点击的相对地址，比如用户点击了E://myImage/3.jpg
        //然后把相对地址进行赋值给img的src属性呢？我们平常使用也是直接获取图片的地址赋值给src，然后图片就可以显示了，
        // 但是我在思否提问，并且后来在MDN文档明确看到下面这段话，总结为出于安全原因，web不能直接读取用户电脑的数据，包括相对地址
        // 所以此处只能通过鼠标点击对象获取file，即获取点击的图片，然后转成base64，在进行赋值给src实现在线预览；或者使用URL.createObjectURL(),然后传入文件对象或者blob类型,并且文件对象本身就是一种特殊的blob类型，它是基于blob类型的;文件接口是html5体系建立起来后给的一种前端上传下载的解决方案。
        // 此处附上我当时在思否的提问，关于为什么不直接图片相对地址实现在线预览的回答：
        // 这个是MDN文档的明确规定,你打开这个地址,然后下拉到注意事项【大概下拉0.6个window窗口高度可以看到】，里面有写：https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/Input/file
        console.log('***********************************')
        // 1.2图片预览实现
        // 预览图片的实现 第一种方法 URL.createObjectURL 生成一个本页面的url地址符
        this.imgPreview1 = window.URL.createObjectURL(this.fileData)//传入文件对象,即一个blob大型二进制类型，实现预览图片1的显示
        console.log("图片的URL.createObjectURL生成的预览地址:",this.imgPreview1);
        // 预览图片的实现 二种方法 readAsDataURL()生成base64
        var reader = new FileReader();//读取文件
        reader.onload = (e) => {//文件读取完毕会触发这里的回调，详细用法看MDN
          this.imgPreview2 = reader.result//读取结果的base64编码赋值给预览图片2
          this.fileStream = reader.result//读取结果的base64编码赋值给fileData,用于fileData携带base64的数据集流提交到后台，后台再发送到七牛云
          console.log('***********************************')
          console.log("图片的base64的二进制流：",this.imgPreview2)
          this.beforePreview_title = ''//此处与本demo无关,只是为了控制样式
        }
        reader.readAsDataURL(this.fileData);//以base64读取文件对象 细节同样MDN有 此处读取完毕会触发上面的onload，原理和window.onload()一样
      },
      // 2. 不同于前台上传的是，使用后台完成上传，我们只需要把图片数据发送给后台，其他的任务交给后台，待后台上传完毕，会返回一个图片的url资源返回给我们
      submit(){ 
        //成功预览的情况下，才发送数据到后台
        if(this.imgPreview1!=''&&this.imgPreview2!=''){
           //2.1 提交文件数据到后台
         axios.request({
         url:"/api_hu66/uploadBybackend",
         method:'post',
         data:{
           key:this.fileName,//文件名
           fileData:this.fileStream,//文件数据 要是前台上传，这里只传本地的文件的地址信息就够了，但是要把文件发给后台，必须传递全部文件信息,此处为文件流
         }
       }).then((res) => {
          //  console.log("*********************************");
           console.log("把图片数据全部发送到,使用后台完成上传图片,后台的响应信息：", res);
           this.imgSrc = res.data.imgSrc;
           console.log("图片的线上地址:",this.imgSrc);
           window.URL.revokeObjectURL(this.fileData);//卸载预览
           this. beforePreview_title = '上传图片吧,可以生成预览'//恢复初始化
           this.imgPreview1 = '';//恢复初始化
           this.imgPreview2 = ''//恢复初始化
           this.$message({
          message: '上传成功!',
          type: 'success'
        });
         })
        }else{
          this.$message('已完成上传!');
        }
      }
    },
	}
</script>
<style>
.backuploadByH5 {
  z-index: 2;
  padding-top: 100px;
  position: relative;
  width: 300px;
  margin: 0 auto;
}
.upload__tip{
  margin:15px auto;
}
.preview{
  width: 100%;
  display: flex;
  justify-content: center;
  color: brown;
  font-weight: 700;
}
.previewBycreateObjectURL{
  margin-right: 50px;
  margin-bottom:100px ;
}
.btnBox_back{
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  width: 100vw;
  height: 50px;
  cursor: pointer;
}
.hoverbtn_back{
  display: inline-block;
  background-color: brown;
  color: aquamarine;
  cursor: pointer;
	padding: 5px 10px;
  height: 200px;
	border-radius: 5px;
	border: 1px ridge black;
	margin-right: 20px;
	height: auto;
  transition: all 0.3s;
}
.hoverbtn_back:hover{
  color: #ffffff;
  display: inline-block;
  transform: scale(1.1);
}
</style>
